package com.uduemc.biso.node.web.component;

import java.util.Arrays;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * 去除关闭服务时报错的问题
 * org.springframework.beans.factory.BeanCreationNotAllowedException: Error
 * creating bean with name 'eurekaAutoServiceRegistration': Singleton bean
 * creation not allowed while singletons of this factory are in destruction (Do
 * not request a bean from a BeanFactory in a destroy method implementation!)
 * 
 * @author guanyi
 *         根本原因是：当关闭ApplicationContext，会关闭所有的单例：先是eurekaAutoServiceRegistration，然后是feignContext。当关闭feignContext时，
 *         会关闭与每个FeignClient关联的ApplicationContext，因为eurekaAutoServiceRegistration监听ContextClosedEvent，ContextClosedEvent的所有事件将会被发送到那个bean上，
 *         因为它已经被关闭了，所以会出现上面异常。
 */
@Component
public class FeignBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		if (containsBeanDefinition(beanFactory, "feignContext", "eurekaAutoServiceRegistration")) {
			BeanDefinition bd = beanFactory.getBeanDefinition("feignContext");
			bd.setDependsOn("eurekaAutoServiceRegistration");
		}
	}

	private boolean containsBeanDefinition(ConfigurableListableBeanFactory beanFactory, String... beans) {
		return Arrays.stream(beans).allMatch(beanFactory::containsBeanDefinition);
	}

}
